package com.example.demo.service.impl;


import com.example.demo.entity.Cart;
import com.example.demo.entity.Menu;
import com.example.demo.entity.Order;
import com.example.demo.entity.OrderItem;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.CodeEnum;
import com.example.demo.mapper.*;
import com.example.demo.service.CartService;
import com.example.demo.service.OrderService;
import com.example.demo.service.model.OrderModel;
import com.example.demo.util.KafkaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;


@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    //购物车key的前缀
    public static final String CART_KEY = "cart:user:";


    /**
     * @Author chenqiuran
     * @Description //TODO 根据ID获取订单信息
     * @Date 7:59 2021/8/29
     * @Param [Id]
     * @return com.example.demo.service.model.OrderModel
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public OrderModel findById(Long Id) throws BusinessException {
        Order order = orderMapper.findById(Id);
        //订单是否存在
        if(!orderMapper.existOrder(Id)){
            throw new BusinessException(CodeEnum.NOT_EXIST_ORDER.getMsg(),CodeEnum.NOT_EXIST_ORDER.getCode());
        }
        //订单是否是被删除状态
        if(orderMapper.isDelete(Id)){
            throw new BusinessException(CodeEnum.ORDER_DELETED.getMsg(),CodeEnum.ORDER_DELETED.getCode());
        }
        OrderModel orderModel = converFromOrderToOrderModel(order);
        return orderModel;
    }


    /**
     * @Author chenqiuran
     * @Description //TODO 根据用户ID获取用户所有订单
     * @Date 7:59 2021/8/29
     * @Param [UserId, index, limit]
     * @return java.util.List<com.example.demo.service.model.OrderModel>
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public List<OrderModel> findAllOrderByUserIdWithRange(Long UserId,Integer index,Integer limit) {
        List<Order> orderList = orderMapper.findAllOrderByUserId(UserId,index,limit);
        List<OrderModel> orderModelList = convertFromOrderListToOrderModelList(orderList);
        return orderModelList;
    }


    /**
     * @Author chenqiuran
     * @Description //TODO 根据菜品名查找用户的带有该菜品的订单
     * @Date 8:00 2021/8/29
     * @Param [UserId, MenuName, index, limit]
     * @return java.util.List<com.example.demo.service.model.OrderModel>
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public List<OrderModel> findUserOrderByMenuName(Long userId, String menuName,Integer index,Integer limit) {
        List<Order> orderList = orderMapper.findUserOrderByMenuName(userId,menuName,index,limit);
        List<OrderModel> orderModelList = convertFromOrderListToOrderModelList(orderList);
        return orderModelList;
    }

    /**
     * @Author chenqiuran
     * @Description //TODO 创建订单
     * @Date 8:00 2021/8/29
     * @Param [orderModel]
     * @return java.lang.Boolean
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean createOrder(OrderModel orderModel) throws BusinessException {
        Order order = new Order();
        order.setUserId(orderModel.getUserId());
        order.setDate(orderModel.getDate());
        order.setNotes(orderModel.getNotes());
        String founder = userMapper.findById(orderModel.getUserId()).getUsername();
        order.setFounder(founder);
        order.setFoundTime(new Timestamp(System.currentTimeMillis()));
        order.setState(0);//未付款
        int insertOrderRow = orderMapper.createOrder(order);
        List<OrderItem> orderItemList = orderModel.getOrderItemList();
        if(orderItemList == null){
            //没有订单项
            throw new BusinessException(CodeEnum.NULL_ORDER_ITEM.getMsg(),CodeEnum.NULL_ORDER_ITEM.getCode());
        }
        orderItemList.forEach(orderItem -> {
            orderItem.setOrderId(order.getId());
            orderItem.setFounder(founder);
            orderItem.setFoundTime(new Timestamp(System.currentTimeMillis()));
        });
        int insertOrderItemRow = orderItemMapper.addAllOrderItem(orderItemList);
        return insertOrderRow+insertOrderItemRow>1;
    }

    /**
     * @Author chenqiuran
     * @Description //TODO 确认订单完成
     * @Date 8:00 2021/8/29
     * @Param [userId, orderId]
     * @return java.lang.Boolean
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean confirmOrder(Long orderId) throws BusinessException {
        if(orderMapper.existOrder(orderId)){

            //订单是否是被删除状态
            if(orderMapper.isDelete(orderId)){
                throw new BusinessException(CodeEnum.ORDER_DELETED.getMsg(),CodeEnum.ORDER_DELETED.getCode());
            }

            int state = orderMapper.findById(orderId).getState();
            switch (state){
                    //订单未付款，不可确认
                case 0:
                    throw new BusinessException(CodeEnum.UNPAID_ORDER.getMsg(),CodeEnum.UNPAID_ORDER.getCode());
                    //未发货，不可确认
                case 1:
                    throw new BusinessException(CodeEnum.UNDELIVERED_ORDER.getMsg(),CodeEnum.UNDELIVERED_ORDER.getCode());
                    //已发货，可以确认
                case 2:
                    return orderMapper.confirmOrder(orderId)>0;
                    //已完成，不可确认
                case 3: throw new BusinessException(CodeEnum.FINISHED_ORDER.getMsg(),CodeEnum.FINISHED_ORDER.getCode());
                    //状态错误
                default:throw new BusinessException(CodeEnum.ORDER_STATE_ERROR.getMsg(),CodeEnum.ORDER_STATE_ERROR.getCode());
            }
        }else {
            //订单不存在
            throw new BusinessException(CodeEnum.NOT_EXIST_ORDER.getMsg(),CodeEnum.NOT_EXIST_ORDER.getCode());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean deliverOrder(Long orderId) throws BusinessException {
        if(orderMapper.existOrder(orderId)){

            //订单是否是被删除状态
            if(orderMapper.isDelete(orderId)){
                throw new BusinessException(CodeEnum.ORDER_DELETED.getMsg(),CodeEnum.ORDER_DELETED.getCode());
            }

            int state = orderMapper.findById(orderId).getState();
            switch (state){
                //订单未付款
                case 0:
                    throw new BusinessException(CodeEnum.UNPAID_ORDER.getMsg(),CodeEnum.UNPAID_ORDER.getCode());
                    //确认发货
                case 1:
                    return orderMapper.deliverOrder(orderId)>0;
                    //已发货
                case 2:
                    throw new BusinessException(CodeEnum.DELIVERED_ORDER.getMsg(),CodeEnum.DELIVERED_ORDER.getCode());
                //已完成
                case 3: throw new BusinessException(CodeEnum.FINISHED_ORDER.getMsg(),CodeEnum.FINISHED_ORDER.getCode());
                    //状态错误
                default:throw new BusinessException(CodeEnum.ORDER_STATE_ERROR.getMsg(),CodeEnum.ORDER_STATE_ERROR.getCode());
            }
        }else {
            //订单不存在
            throw new BusinessException(CodeEnum.NOT_EXIST_ORDER.getMsg(),CodeEnum.NOT_EXIST_ORDER.getCode());
        }
    }

    /**
     * @Author chenqiuran
     * @Description //TODO 删除订单(逻辑删除)
     * @Date 8:00 2021/8/29
     * @Param [userId, orderId]
     * @return java.lang.Boolean
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean deleteOrder(Long orderId) throws BusinessException {
        //订单是否存在
        if(orderMapper.existOrder(orderId)){
            //订单是否是被删除状态
            if(!orderMapper.isDelete(orderId)){
                int deleteOrderRow = orderMapper.deleteOrder(orderId);
                return deleteOrderRow>0;
            }else {
                throw new BusinessException(CodeEnum.ORDER_DELETED.getMsg(),CodeEnum.ORDER_DELETED.getCode());
            }
        }else {
            //订单不存在
            throw new BusinessException(CodeEnum.NOT_EXIST_ORDER.getMsg(),CodeEnum.NOT_EXIST_ORDER.getCode());
        }
    }

    @Override
    public List<OrderModel> findAllOrder(Integer index, Integer limit) {
        List<Order> orderList = orderMapper.findAllOrder(index,limit);
        List<OrderModel> orderModelList = convertFromOrderListToOrderModelList(orderList);
        return orderModelList;
    }

    @Override
    public List<OrderModel> findAllByMenuName(String menuName, Integer index, Integer limit) {
        List<Order> orderList = orderMapper.findAllByMenuName(menuName,index,limit);
        List<OrderModel> orderModelList = convertFromOrderListToOrderModelList(orderList);
        return orderModelList;
    }

    @Override
    public List<OrderModel> findAllByTelephone(String telephone, Integer index, Integer limit) {
        List<Order> orderList = orderMapper.findAllByTelephone(telephone,index,limit);
        List<OrderModel> orderModelList = convertFromOrderListToOrderModelList(orderList);
        return orderModelList;
    }

    @Override
    public List<OrderModel> findAllByUserName(String userName, Integer index, Integer limit) {
        List<Order> orderList = orderMapper.findAllByUserName(userName,index,limit);
        List<OrderModel> orderModelList = convertFromOrderListToOrderModelList(orderList);
        return orderModelList;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean payForOrder(Long orderId, Long userId) throws BusinessException {
        Order order = orderMapper.findById(orderId);
        OrderModel orderModel = converFromOrderToOrderModel(order);
        BigDecimal totalPrice = orderModel.getTotalPrice();//获得总价
        //先检查状态再检查余额
        int state = orderModel.getState();
        switch (state){
            //订单未付款
            case 0:
                orderMapper.payOrder(orderId);//改订单状态为已付款
                //若余额小于总价
                if(userMapper.findById(userId).getBalance().compareTo(totalPrice)==-1){
                    throw new BusinessException(CodeEnum.INSUFFICIENT_BALANCE.getMsg(),CodeEnum.INSUFFICIENT_BALANCE.getCode());
                }
                userMapper.deduction(userId,totalPrice);//减余额
                return true;
            //订单已付款
            case 1:
                throw new BusinessException(CodeEnum.PAID_ORDER.getMsg(),CodeEnum.PAID_ORDER.getCode());
            //已发货
            case 2:
                throw new BusinessException(CodeEnum.DELIVERED_ORDER.getMsg(),CodeEnum.DELIVERED_ORDER.getCode());
            //已完成
            case 3: throw new BusinessException(CodeEnum.FINISHED_ORDER.getMsg(),CodeEnum.FINISHED_ORDER.getCode());
            //状态错误
            default:throw new BusinessException(CodeEnum.ORDER_STATE_ERROR.getMsg(),CodeEnum.ORDER_STATE_ERROR.getCode());
        }
    }

    /**
     * @Author chenqiuran
     * @Description //TODO 通过购物车、用户id、备注完成订单和订单项数据的插入
     * @Date 22:25 2021/8/31
     * @Param [cartList, userId, notes]
     * @return java.lang.Boolean
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean createOrderByCart(Long userId, String notes) throws BusinessException {
        //0.从数据库获取购物车
        List<Cart> cartList = cartMapper.findAll(userId);
        //1.创建order
        Order order = new Order();
        order.setState(0);
        order.setNotes(notes);
        String founder = userMapper.findById(userId).getUsername();
        Timestamp now = new Timestamp(System.currentTimeMillis());
        order.setFounder(founder);
        order.setFoundTime(now);
        order.setDate(now);
        order.setUserId(userId);
        int orderResult = orderMapper.createOrder(order);
        //2.创建orderItemList
        List<OrderItem> orderItemList = new ArrayList<>();
        for (Cart cart : cartList) {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(order.getId());
            orderItem.setMenuId(cart.getMenuId());
            orderItem.setNumber(cart.getNumber());
            orderItem.setFounder(founder);
            orderItem.setFoundTime(now);
            orderItemList.add(orderItem);

        }
        if(orderItemList == null){
            //没有订单项
            throw new BusinessException(CodeEnum.NULL_ORDER_ITEM.getMsg(),CodeEnum.NULL_ORDER_ITEM.getCode());
        }
        int orderItemResult = orderItemMapper.addAllOrderItem(orderItemList);
        //3.数据库删除
        cartMapper.delAllCart(userId);
        //4.redis删除
        String key = CART_KEY + userId;
        for (Cart cart : cartList) {
            redisTemplate.opsForHash().delete(key, cart.getMenuId().toString());
        }
        return orderResult+orderItemResult>1;
    }

    /**
     * @Author chenqiuran
     * @Description //TODO 将orderList转化为orderModelList
     * @Date 10:49 2021/8/29
     * @Param [orderList]
     * @return java.util.List<com.example.demo.service.model.OrderModel>
     **/
    public List<OrderModel> convertFromOrderListToOrderModelList(List<Order> orderList){
        List<OrderModel> orderModelList = new ArrayList<>();
        orderList.forEach(order ->{
            OrderModel orderModel = new OrderModel();
            orderModel.setId(order.getId());
            orderModel.setUserId(order.getUserId());
            orderModel.setDate(order.getDate());
            orderModel.setNotes(order.getNotes());
            orderModel.setState(order.getState());
            orderModel.setIsDelete(order.getIsDelete());
            //获取订单项集合
            List<OrderItem> orderItemList = orderItemMapper.findAllOrderItemByOrderId(order.getId());
            orderModel.setOrderItemList(orderItemList);
            //计算总价格
            BigDecimal totalPrice = new BigDecimal("0.0");
            for (OrderItem orderItem : orderItemList) {
                Menu menu = menuMapper.findById(orderItem.getMenuId());
                BigDecimal x =  menu.getPrice().multiply(new BigDecimal(orderItem.getNumber()));
                totalPrice = totalPrice.add(x);
            }
            orderModel.setTotalPrice(totalPrice);
            orderModelList.add(orderModel);
        });
        return orderModelList;
    }

    /**
     * @Author chenqiuran
     * @Description //TODO 将order转化为orderModel
     * @Date 22:26 2021/8/31
     * @Param [order]
     * @return com.example.demo.service.model.OrderModel
     **/
    public OrderModel converFromOrderToOrderModel(Order order){
        OrderModel orderModel = new OrderModel();
        orderModel.setId(order.getId());
        orderModel.setUserId(order.getUserId());
        orderModel.setDate(order.getDate());
        orderModel.setNotes(order.getNotes());
        orderModel.setState(order.getState());
        orderModel.setIsDelete(order.getIsDelete());
        //获取订单项集合
        List<OrderItem> orderItemList = orderItemMapper.findAllOrderItemByOrderId(order.getId());
        orderModel.setOrderItemList(orderItemList);
        //计算总价格
        BigDecimal totalPrice = new BigDecimal("0.0");
        for (OrderItem orderItem : orderItemList) {
            Menu menu = menuMapper.findById(orderItem.getMenuId());
            BigDecimal x =  menu.getPrice().multiply(new BigDecimal(orderItem.getNumber()));
            totalPrice = totalPrice.add(x);
        }
        orderModel.setTotalPrice(totalPrice);
        return orderModel;
    }
}

